package com.liyuxiang.graph.service;

import com.liyuxiang.graph.entity.SymptomCollectionForm;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * AI智能症状表单生成服务 - 根据用户症状动态生成个性化表单
 */
@Service
public class SymptomFormGeneratorService {
    
    private static final Logger logger = LoggerFactory.getLogger(SymptomFormGeneratorService.class);
    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;
    
    public SymptomFormGeneratorService(@Qualifier("simpleCharClientBuilder") ChatClient.Builder chatClientBuilder, 
                                     ObjectMapper objectMapper) {
        this.chatClient = chatClientBuilder.build();
        this.objectMapper = objectMapper;
    }
    
    /**
     * AI智能生成症状收集表单 - 使用结构化输出
     */
    public SymptomCollectionForm generateSymptomForm(String initialSymptom, String userId) {
        logger.info("AI智能生成症状表单 - 用户ID: {}, 症状: {}", userId, initialSymptom);
        
        try {
            // 构建AI提示词 - 简化版，让AI更容易生成完整响应
            String prompt = "根据症状\"" + initialSymptom + "\"生成症状收集表单配置。\n\n" +
                    "要求：\n" +
                    "1. 生成3个关键字段\n" +
                    "2. 第一个字段：症状描述(TEXTAREA)\n" +
                    "3. 第二个字段：症状位置(RADIO，3个选项)\n" +
                    "4. 第三个字段：症状程度(SLIDER，1-10)\n" +
                    "5. 根据具体症状调整位置选项\n" +
                    "6. 只返回JSON格式\n\n" +
                    "JSON结构：\n" +
                    "{\n" +
                    "  \"title\": \"症状详情收集\",\n" +
                    "  \"description\": \"请填写症状信息\",\n" +
                    "  \"requireAll\": false,\n" +
                    "  \"fields\": [...]\n" +
                    "}";
            
            logger.info("发送AI结构化表单生成请求");
            
            // 使用结构化输出 - 直接生成实体类对象
            SymptomCollectionForm form = chatClient.prompt()
                    .user(prompt)
                    .call()
                    .entity(SymptomCollectionForm.class);
            
            // 验证生成的表单
            if (form != null && form.getFields() != null && !form.getFields().isEmpty()) {
                logger.info("AI结构化表单生成成功 - 字段数: {}", form.getFields().size());
                return form;
            } else {
                logger.warn("AI生成的表单为空，使用备用方法");
                return generateFormWithStringParsing(initialSymptom, userId);
            }
            
        } catch (Exception e) {
            logger.error("AI结构化表单生成失败 - 用户ID: {}, 错误: {}", userId, e.getMessage(), e);
            logger.info("尝试使用JSON字符串解析方法");
            return generateFormWithStringParsing(initialSymptom, userId);
        }
    }
    
    /**
     * 备用方法：使用JSON字符串解析
     */
    private SymptomCollectionForm generateFormWithStringParsing(String initialSymptom, String userId) {
        try {
            // 使用更简短的提示词减少截断风险
            String shortPrompt = "症状：" + initialSymptom + "\n" +
                    "生成JSON表单，包含3个字段：\n" +
                    "1.症状描述(TEXTAREA)\n" +
                    "2.症状位置(RADIO)\n" +
                    "3.症状程度(SLIDER)\n\n" +
                    "JSON：";
            
            String aiResponse = chatClient.prompt()
                    .user(shortPrompt)
                    .call()
                    .content();
            
            logger.info("备用方法收到AI响应，长度: {}", aiResponse.length());
            
            SymptomCollectionForm form = parseJsonToForm(aiResponse);
            logger.info("备用方法解析成功 - 字段数: {}", form.getFields().size());
            return form;
            
        } catch (Exception e) {
            logger.error("备用方法也失败 - 错误: {}", e.getMessage(), e);
            return getFallbackForm(initialSymptom);
        }
    }
    
    /**
     * 使用ObjectMapper直接解析JSON到实体类
     */
    private SymptomCollectionForm parseJsonToForm(String response) {
        try {
            logger.info("AI响应内容前300字符: {}", response.substring(0, Math.min(300, response.length())));
            
            // 提取JSON部分
            int startIndex = response.indexOf('{');
            int endIndex = response.lastIndexOf('}') + 1;
            
            if (startIndex >= 0 && endIndex > startIndex) {
                String jsonStr = response.substring(startIndex, endIndex);
                logger.info("提取JSON长度: {}", jsonStr.length());
                
                // 如果JSON不完整，尝试修复
                if (!isCompleteJson(jsonStr)) {
                    logger.warn("检测到不完整JSON，尝试修复");
                    jsonStr = repairIncompleteJson(jsonStr);
                }
                
                // 直接反序列化为实体类
                SymptomCollectionForm form = objectMapper.readValue(jsonStr, SymptomCollectionForm.class);
                
                // 验证表单完整性
                if (form.getFields() == null || form.getFields().isEmpty()) {
                    throw new RuntimeException("表单字段为空");
                }
                
                logger.info("成功解析表单 - 标题: {}, 字段数: {}", form.getTitle(), form.getFields().size());
                return form;
                
            } else {
                throw new RuntimeException("未找到有效JSON结构");
            }
            
        } catch (Exception e) {
            logger.error("JSON解析失败: {}", e.getMessage());
            logger.error("原始响应: {}", response);
            throw new RuntimeException("表单JSON解析失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 检查JSON是否完整
     */
    private boolean isCompleteJson(String jsonStr) {
        int braceCount = 0;
        int bracketCount = 0;
        
        for (char c : jsonStr.toCharArray()) {
            if (c == '{') braceCount++;
            if (c == '}') braceCount--;
            if (c == '[') bracketCount++;
            if (c == ']') bracketCount--;
        }
        
        return braceCount == 0 && bracketCount == 0;
    }
    
    /**
     * 修复不完整的JSON
     */
    private String repairIncompleteJson(String jsonStr) {
        logger.info("开始修复JSON");
        
        StringBuilder repaired = new StringBuilder(jsonStr);
        
        // 统计括号
        int openBraces = 0;
        int closeBraces = 0;
        int openBrackets = 0;
        int closeBrackets = 0;
        
        for (char c : jsonStr.toCharArray()) {
            switch (c) {
                case '{' -> openBraces++;
                case '}' -> closeBraces++;
                case '[' -> openBrackets++;
                case ']' -> closeBrackets++;
            }
        }
        
        // 如果在数组内部被截断，先补全当前对象
        if (jsonStr.endsWith(",")) {
            repaired.setLength(repaired.length() - 1); // 移除最后的逗号
        }
        
        // 如果字符串以不完整的对象结尾，尝试简单修复
        String jsonTail = jsonStr.substring(Math.max(0, jsonStr.length() - 50)).trim();
        if (jsonTail.endsWith("\"label\":") || jsonTail.contains("{\"value\":")) {
            // 如果在对象中间被截断，删除不完整的部分
            int lastCompleteObject = jsonStr.lastIndexOf("},");
            if (lastCompleteObject > 0) {
                repaired = new StringBuilder(jsonStr.substring(0, lastCompleteObject + 1));
            }
        }
        
        // 补全缺失的右括号
        while (closeBrackets < openBrackets) {
            repaired.append("]");
            closeBrackets++;
        }
        
        while (closeBraces < openBraces) {
            repaired.append("}");
            closeBraces++;
        }
        
        String repairedJson = repaired.toString();
        logger.info("修复后JSON长度: {} -> {}", jsonStr.length(), repairedJson.length());
        
        return repairedJson;
    }
    
    /**
     * 备用表单生成 - 当AI失败时使用
     */
    private SymptomCollectionForm getFallbackForm(String symptom) {
        logger.warn("使用备用表单生成 - 症状: {}", symptom);
        
        SymptomCollectionForm form = new SymptomCollectionForm();
        form.setTitle("症状信息收集");
        form.setDescription("请填写您的症状信息");
        form.setRequireAll(false);
        
        // 创建基本表单字段
        List<SymptomCollectionForm.FormField> fields = Arrays.asList(
            createTextAreaField("symptom_description", "症状描述", "请详细描述您的症状", "💊", true, "详细描述有助于诊断"),
            createRadioField("symptom_severity", "症状严重程度", "⚠️", true,
                Arrays.asList(
                    new SymptomCollectionForm.FieldOption("mild", "轻微", "😐", "success", false),
                    new SymptomCollectionForm.FieldOption("moderate", "中度", "😣", "warning", true),
                    new SymptomCollectionForm.FieldOption("severe", "严重", "😰", "danger", false)
                )
            ),
            createRadioField("duration", "持续时间", "🕐", true,
                Arrays.asList(
                    new SymptomCollectionForm.FieldOption("recent", "最近出现", "🕐", "success", true),
                    new SymptomCollectionForm.FieldOption("days", "几天了", "📅", "primary", false),
                    new SymptomCollectionForm.FieldOption("weeks", "几周了", "📋", "warning", false)
                )
            )
        );
        
        form.setFields(fields);
        return form;
    }
    
    // 创建表单字段的辅助方法
    private SymptomCollectionForm.FormField createTextAreaField(String key, String label, String placeholder, 
                                                               String icon, boolean required, String description) {
        SymptomCollectionForm.FormField field = new SymptomCollectionForm.FormField();
        field.setKey(key);
        field.setLabel(label);
        field.setType(SymptomCollectionForm.FieldType.TEXTAREA);
        field.setRequired(required);
        field.setPlaceholder(placeholder);
        field.setIcon(icon);
        field.setDescription(description);
        field.setMaxLength(200);
        return field;
    }
    
    private SymptomCollectionForm.FormField createRadioField(String key, String label, String icon, boolean required,
                                                           List<SymptomCollectionForm.FieldOption> options) {
        SymptomCollectionForm.FormField field = new SymptomCollectionForm.FormField();
        field.setKey(key);
        field.setLabel(label);
        field.setType(SymptomCollectionForm.FieldType.RADIO);
        field.setRequired(required);
        field.setIcon(icon);
        field.setOptions(options);
        return field;
    }
}